home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
docs
/
ippon
/
ver
/
013
/
eshot.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-07-07
|
3KB
|
117 lines
/* eshot.c */
#include <stdio.h>
#include <xsp2lib.h>
#include "main.h"
#include "player.h"
#include "eshot.h"
#define PALET_ESHOT 0x0300
#define ESHOT_MAX 200 /* 敵弾最大数 */
static ESHOT eshot[ESHOT_MAX]; /* ワーク */
/* ゲーム開始時に呼ばれる */
void EshotInit (void)
{
int i;
/* リストをつなげる */
eshot_top = NULL;
eshot_null_top = eshot;
for (i = 0; i < ESHOT_MAX; i++)
eshot[i].next = &eshot[i + 1];
eshot[ESHOT_MAX - 1].next = NULL;
}
/* 敵弾出現時に呼ばれる */
void EshotAlloc (short type, signed short x, signed short y, unsigned char speed, unsigned char angle)
{
ESHOT *p;
if (eshot_null_top == NULL) /* ワークの空きはあるか? */
return;
p = eshot_null_top;
eshot_null_top = p->next;
p->next = eshot_top;
eshot_top = p;
p->lx = (x - 8) << 16; /* (8,8) がスプライト座標の中心なので補正 */
p->ly = (y - 8) << 16;
p->vx = xytable[speed][angle].x;
p->vy = xytable[speed][angle].y;
p->hit_p = 3; /* 速度を 3.0 未満にする事 */
p->pt = sp_eshot + 1;
p->info = PALET_ESHOT | PRIORITY_ESHOT;
}
/* 垂直同期ごとに呼ばれる */
void EshotMove (void)
{
ESHOT *p, *q;
signed short pl_x = player->x - 8, pl_y = player->y - 8;
#ifdef DEBUG
eshot_sum = 0;
#endif
p = eshot_top; /* 現在注目しているワーク */
q = NULL; /* 1つ前のワーク(ワーク削除時に必要) */
while (p != NULL) {
signed short p_x, p_y;
#ifdef DEBUG
eshot_sum++;
#endif
/* 速度を足して上位ワード(固定整数部)だけ取り出す */
p_x = p->x = (p->lx += p->vx) >> 16;
p_y = p->y = (p->ly += p->vy) >> 16;
/* 敵弾が画面外に出たか? */
/* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16)) {
/* 敵弾が画面外へ出たので消去 */
if (q == NULL) { /* リストの一番最初を削除 */
eshot_top = p->next;
p->next = eshot_null_top;
eshot_null_top = p;
q = NULL;
p = eshot_top;
} else {
q->next = p->next;
p->next = eshot_null_top;
eshot_null_top = p;
p = q->next;
}
} else {
/* 画面外へ出ていない時 */
/* 敵弾と自機の当たり判定 */
/* この辺の最適化は -fstrings-reduce が頑張ってくれるハズ */
signed short t, t2 = p->hit_p;
if (((t = p_y - t2) <= pl_y)
&& ((t += (short) (t2 << 1)) >= pl_y)
&& ((t = p_x + t2) >= pl_x)
&& ((t -= (short) (t2 << 1)) <= pl_x)) {
if (player->status == PLAYER_STATUS_ALIVE)
player->status = PLAYER_STATUS_DEAD;
} else {
xsp_set_st (p);
}
q = p;
p = p->next;
}
}
}